package com.gesonet.common.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;

import javax.xml.bind.DatatypeConverter;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
 * @Description: 日期时间工具类
 * @author QXX
 * @date 2014年10月13日 下午1:07:20
 */
public abstract class DateUtils {

	private static final Logger LOG = LoggerFactory.getLogger(DateUtils.class);

	/**格式：yyyy-MM-dd HH:mm:ss*/
	public static final String DEFAULT_FORMAT = "yyyy-MM-dd HH:mm:ss";
	/**格式：yyyyMMdd*/
	public static final String SHORT_FORMAT = "yyyyMMdd";
	/**格式：yyyy-MM-dd*/
	public static final String SHORT_FORMAT_EX = "yyyy-MM-dd";
	/**格式：yyyyMMddHH*/
	public static final String SHORT_FORMAT_HOUR = "yyyyMMddHH";
	/**格式：yyyyMM*/
	public static final String SHORT_FORMAT_MONTH = "yyyyMM";
	/**格式：yyyyMMddHHmmssS*/
	public static final String LONG_FORMAT = "yyyyMMddHHmmssS";
	/**格式：yyyyMMddHHmmss*/
	public static final String FORMAT_YMDHMS = "yyyyMMddHHmmss";
//	/**Nginx日志配置的请求时间格式*/
//	private static final String FORMAT_TIME_ISO8601 = "yyyy-MM-dd'T'HH:mm:ssz";
	
//	public static final SimpleDateFormat ISO8601_DATEFORMAT = new SimpleDateFormat(FORMAT_TIME_ISO8601);
	/**格式：yyyy-MM-dd HH:mm:ss*/
	public static final SimpleDateFormat DEFAULT_DATEFORMAT = new SimpleDateFormat(DEFAULT_FORMAT);

	public static String format(Date date) {
		return DEFAULT_DATEFORMAT.format(date);
	}

	/**
	 * @author QXX
	 * @date 2014年10月13日 上午11:54:05
	 * @Description: 字符串格式转换为Date类型 
	 * @param iso8601Time ：2014-10-12T20:41:17+08:00
	 * @return Date
	 * @throws
	 */
	public static Date iso8601TimeStr2Date(String iso8601Time){
		try {
			return DatatypeConverter.parseDateTime(iso8601Time).getTime();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
			LOG.error("iso8601TimeStr2Date error : {}",iso8601Time);
		}
		return null;
	}
	
	/**
	 * @author QXX
	 * @date 2014年10月13日 下午1:16:17
	 * @Description: 时间字符串转换为Date对象 
	 * @param dateStr yyyyMMddHHmmss
	 * @return Date
	 * @throws
	 */
	public static Date yyyyMMddHHmmss2Date(String dateStr){
		if (StringUtils.isNotBlank(dateStr)) {
			SimpleDateFormat sdf = new SimpleDateFormat(FORMAT_YMDHMS);
			try {
				return sdf.parse(dateStr);
			} catch (ParseException e) {
				e.printStackTrace();
				LOG.error("yyyyMMddHHmmss2Date error:{}",dateStr);
			}
		}
		return null;
	}
	
	/**
	 * @author QXX
	 * @date 2014年10月13日 下午2:32:36
	 * @Description: 日期时间格式化 
	 * @param date 日期时间
	 * @param format 格式化格式
	 * @return
	 * @throws
	 */
	public static String format(Date date, String format) {
		if (date == null) {
			return null;
		}
		if (format == null)
			return format(date);
		SimpleDateFormat dateFormat = new SimpleDateFormat(format);
		return dateFormat.format(date);
	}

	/**
	 * @author QXX
	 * @date 2014年10月14日 下午2:11:59
	 * @Description: 默认格式化格式为yyyy-MM-dd HH:mm:ss的字符串 
	 * @param source 时间字符串 yyyy-MM-dd HH:mm:ss
	 * @return
	 * @throws
	 */
	public static Date parse(String source) {
		try {
			Date date = DEFAULT_DATEFORMAT.parse(source);
			return date;
		} catch (Exception ex) {
			ex.printStackTrace();
			LOG.error("Date parse exception. source: {}", source);
		}
		return null;
	}

	/**
	 * @author QXX
	 * @date 2014年10月14日 下午2:10:11
	 * @Description: 时间字符串格式话 
	 * @param source 时间字符串
	 * @param format 时间字符串格式
	 * @return 
	 * @throws
	 */
	public static Date parse(String source, String format) {
		SimpleDateFormat dateFormat = new SimpleDateFormat(format);
		try {
			Date date = dateFormat.parse(source);
			return date;
		} catch (ParseException ex) {
			ex.printStackTrace();
			LOG.error("Date parse exception. source: {}, format: {}", source, format);
		}
		return null;
	}

	/**
	 * @author QXX
	 * @date 2014年10月14日 下午2:13:17
	 * @Description: 日期时间字符串 格式转换 
	 * @param source 原日期时间字符串
	 * @param format 原日期时间字符串的格式
	 * @param desform 目标日期时间字符串的格式
	 * @return 日期时间字符串
	 * @throws
	 */
	public static String format(String source, String format, String desform) {
		Date date = parse(source, format);
		if (date == null) {
			return null;
		}
		SimpleDateFormat dateFormat = new SimpleDateFormat(desform);
		return dateFormat.format(date);
	}

	public static Date getPreMonth(Date date) {
		return getPreMonthByNumber(date, 1);
	}

	public static Date getPreMonthByNumber(Date date, int number) {
		if (date == null) {
			return null;
		}
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);

		int month = calendar.get(Calendar.MONTH);
		calendar.set(Calendar.MONTH, month - number);
		return calendar.getTime();
	}

	public static Date getNextMonthByNumber(Date date, int number) {
		return getPreMonthByNumber(date, -number);
	}

	public static Date getPreDaysDate(Date date, int number) {
		if (date == null) {
			return null;
		}
		long predaysTime = date.getTime() - 1000L * number * 24L * 3600L;
		return new Date(predaysTime);
	}

	public static Date getPreDayDate(Date date) {
		return getPreDaysDate(date, 1);
	}

	public static Date getNextDaysDate(Date date, int number) {
		return getPreDaysDate(date, -number);
	}

	public static String getLastDayOfMonth(int year, int month) {
		Calendar calendar = GregorianCalendar.getInstance(Locale.CHINESE);
		calendar.set(year, month, 1);

		Date date = new Date(calendar.getTimeInMillis() - 86400000L);
		return format(date, "yyyy年M月dd日");
	}

	public static long getDValue2Day(Date start, Date end) {
		long dValue = 0;
		try {
			long l = end.getTime() - start.getTime();
			dValue = l / (24 * 60 * 60 * 1000);
		} catch (Exception e) {
		}
		return dValue;
	}

	/**
	 * 例如：得到12日19:43的上一小时12日18:43
	 */
	public static long getPreviousHour(Date time, int num) {
		long result = 0;
		try {
			Calendar cal = Calendar.getInstance();
			cal.setTime(time);// 日历为今天
			long tm, tm1;
			tm = cal.getTimeInMillis();// 得到当前时间与1970年1月1日0点相距的毫秒数
			tm1 = tm - num * 60 * 60 * 1000;// 得到前一小时与1970年1月1日0点相距的毫秒数
			Date time1 = new Date(tm1);
			SimpleDateFormat sdf = new SimpleDateFormat(SHORT_FORMAT_HOUR);
			result = Long.valueOf(sdf.format(time1));// tm就是前一小时的日期的字符串表示
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	/**
	 * 例如：得到12日19:43的上一分钟
	 */
	public static long getPreviousMinute (Date time, int num) {
		long result = 0;
		try {
			Calendar cal = Calendar.getInstance();
			cal.setTime(time);// 日历为今天
			long tm, tm1;
			tm = cal.getTimeInMillis();// 得到当前时间与1970年1月1日0点相距的毫秒数
			tm1 = tm - num * 60 * 1000;// 得到前一分钟与1970年1月1日0点相距的毫秒数
			Date time1 = new Date(tm1);
			result = time1.getTime();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	public static long getNextHour(Date time, int num) {
		return getPreviousHour(time, -num);
	}

	/**
	 * cc like "14/Nov/2013:00:00:01";
	 * 
	 * @param cc
	 * @return
	 */
	public static String getDateTime(String cc, String format) {
		String result = StringUtils.EMPTY;
		SimpleDateFormat sdf = new SimpleDateFormat("dd/MMM/yyyy:HH:mm:ss", new Locale("English"));
		try {
			if (StringUtils.isBlank(cc)) {
				return result;
			}
			cc = cc.replaceAll("\\[", StringUtils.EMPTY);
			Date date = sdf.parse(cc);
			SimpleDateFormat dateformat = new SimpleDateFormat(format);
			result = dateformat.format(date);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	public static long getDifference(String date1, String date2, String format) {
		long l1 = 0L;
		try {
			SimpleDateFormat df = new SimpleDateFormat(format);
			Date now = df.parse(date1);
			Date date = df.parse(date2);
			l1 = now.getTime() - date.getTime();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return l1;
	}
	
	public static long getSecond(String source, String format){
		long second = 0L;
		try {
			Date tempDate = parse(source, format);
			second = tempDate.getTime() / 1000L;
		} catch (Exception e) {
		}
		return second;
	}

	/**
	 * @author QXX
	 * @date 2014年10月12日 下午3:16:26
	 * @Description: 获取当前月份的最大数 
	 * @return
	 * @throws
	 */
	public static int getCurrentMonthDays() {
		Calendar a = Calendar.getInstance();
		a.set(Calendar.DATE, 1);// 把日期设置为当月第一天
		a.roll(Calendar.DATE, -1);// 日期回滚一天，也就是最后一天
		int maxDate = a.get(Calendar.DATE);
		return maxDate;
	}
	
	/**
	 * 返回指定日期是全年的第几周
	 * @param date
	 * @return
	 */
	public static int getWeek(Date date) {
		int week = -1;
		try {
			Calendar cl = Calendar.getInstance();
			cl.setTime(date);
			week = cl.get(Calendar.WEEK_OF_YEAR);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return week;
	}
	
	/**
	 * 返回指定日期是全年的月份
	 * @param date
	 * @return
	 */
	public static int getYearMonth(Date date) {
		int month = -1;
		try {
			Calendar cl = Calendar.getInstance();
			cl.setTime(date);
			month = cl.get(Calendar.MONTH) + 1;
			if(month < 10){
				month = Integer.valueOf(String.valueOf(cl.get(Calendar.YEAR)) + 0 + month);
			} else {
				month = Integer.valueOf(String.valueOf(cl.get(Calendar.YEAR)) + month);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return month;
	}

	
	/**
	 * @author QXX
	 * @date 2014年10月12日 下午3:25:02
	 * @Description: 根据时间获取当前的年份 
	 * @param date
	 * @return YEAR 年
	 * @throws
	 */
	public static int getYear(Date date){
		Calendar cl = Calendar.getInstance();
		cl.setTime(date);
		return cl.get(Calendar.YEAR);
	}
	
	/**
	 * @author QXX
	 * @date 2014年10月12日 下午3:23:38
	 * @Description: 根据时间获取当前的月份数 
	 * @param date 
	 * @return MONTH 月
	 * @throws
	 */
	public static int getMonth(Date date){
		Calendar cl = Calendar.getInstance();
		cl.setTime(date);
		return cl.get(Calendar.MONTH) + 1;
		
	}
	
	/**
	 * 
	 * @author QXX
	 * @date 2014年10月12日 下午3:27:27
	 * @Description: 获取日期 
	 * @param date
	 * @return DAY_OF_MONTH 日
	 * @throws
	 */
	public static int getDayOfMonth(Date date){
		Calendar cl = Calendar.getInstance();
		cl.setTime(date);
		return cl.get(Calendar.DAY_OF_MONTH);
		
	}
	
	/**
	 * @author QXX
	 * @date 2014年10月21日 上午11:47:13
	 * @Description: 获取昨天的日期 
	 * @return String yyyyMMdd
	 * @throws
	 */
	public static String getYesterdayDate(String format){
		Date yesterday = DateUtils.getPreDayDate(new Date());
		return DateUtils.format(yesterday, format);
	}
	
	/**
	 * @author LCQ
	 * @date 2014年12月2日  下午3:21:13
	 * @description: 获取前i天的日期
	 * @param format
	 * @return
	 */
	public static String getPreDayDate(String format, int i){
		Date preDayDate = getPreDaysDate(new Date(), i);
		return DateUtils.format(preDayDate, format);
	}
	
	
	
	public static void main(String[] args) {
		try {
			Date yesterday = DateUtils.getPreDayDate(new Date());
			String date = DateUtils.format(yesterday, DateUtils.SHORT_FORMAT);
			System.out.println(date);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}
}
